<?php
/**
 * eBusiness 邮乐网接口接单封装
 * 
 * @link        http://baison.com.cn
 * @copyright   Baison, Inc.
 * @package     eBusiness
 */
require_once 'UleRequest.php';
//require_once 'UleItem.php';

class UleStatus {
	/*
	0	交易完成	
	1	交易取消	
	2	退换货	
	3	待付款	
	4	待发货	
	5	已发货	
	6	配货完成	
	7	已签收	
	8	未签收	
	9	已取消	
	 */
	public static $OrderStatus = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
	/*
	R001	商品质量问题	
	R002	快递公司丢失/错失	
	R003	运输中商品损坏	
	R004	发货错误	
	R005	七天无理由	
	R006	买家责任	
	R007	邮递失败	
	R008	商品发货前已损坏	
	R009	退货商品不符	
	R010	其他	
	*/
	public static $ReturnStatus = array('R001', 'R002', 'R003', 'R004', 'R005', 'R006', 'R007', 'R008', 'R009', 'R010');
	/*
	S001	运输途中损坏	
	S002	完整（可重售）	
	S003	完整（不可重售）	
	S004	返回商品与请求商品不符	
	 */
	public static $GoodsStatus = array('S001', 'S002', 'S003', 'S004');
}
class UleRuntimeExecption extends Exception{
    function __construct($errorCode, $errorMessage){
        $errorCode = intval($errorCode);
        if($errorCode > 0) 
           $errorMessage = "Ule API运行失败[{$errorCode}]：".self::getErrorMsg($errorCode).";\n".$errorMessage;
       
        parent::__construct($errorMessage,$errorCode);
    }
    static function getErrorMsg($errorCode){
        if($errorCode <= 0) return;
        
        $arr = include_once('UrlErrMsg.inc.php'); 
        
        return $arr[strval($errorCode)];
    }
}


/**
 *  邮乐网接口接单封装
 * 	<li>如果接口的某些地方发生改变，请及时更新下面api的注释
 * 	<li>增加新的API接口时请注意，获取数据时使用$this->request->get方法来发送请求，更新数据时使用$this->request->post发送请求
 * @author wzd
 *
 */
class UleRuntime {
    function __construct($app_token) {
        if (! is_array ( $app_token ))
            throw new UleRuntimeExecption ( - 1, 'UleRuntime创建失败：参数类型错误' );
		
        if (!array_key_exists('app_key', $app_token)
        		|| !array_key_exists('app_secret', $app_token)
                || !array_key_exists('host_url', $app_token))
            throw new UleRuntimeExecption ( - 1, 'UleRuntime创建失败：参数错误' );
            
        $config = array (                
                'app_key' => $app_token ['app_key'],
        		'key'=>	$app_token ['app_secret'],
                'host_url' => $app_token ['host_url'],
                'app_version' => 'apr_2010_build01',
        		'return_type' => 'json'
                );
        $request = new UleRequest ($config);
       
        $this->request = $request;
         
    }
    function __destruct() {
       $this->request = NULL;
    }
    /**
     * 获取当前商家的商品列表，并能根据传入的搜索条件对商品列表进行过滤，主要用于获取SKU、库存、颜色、规格、名称以及状态等信息。
     * 
     * @param itemSku	String	N	商家Sku。	
	 * @param pageNo	String	N	页码。取值范围:大于零的整数;默认值为1，即返回第一页数据。	
	 * @param pageSize	String	N	每页条数。取值范围:大于零的整数;最大值：200；默认值：50。
	 * 
	 * @return 	<pre>
				array(
					"itemTotal"=>搜索结果总数,
					"item"=>array(
							array(
					            "itemID"=>商品ID
								"itemSku"=>商品唯一SKU,
								"itemName"=>商品名称,
								"itemColor"=> 商品颜色,
								"itemStandard"=> 商品规格,
								"itemPrice"=> 商品价格,
								"itemStoreage "=>商品库存,
								"itemStatus"=>商品状态
							),
							……
						)
				)
				</pre>
     */
    function itemListGet($itemSku=null, $pageNo=null, $pageSize=null) {
        $params = array();
        if ($itemSku) $params['itemSku'] = $itemSku;
        if ($pageNo) $params['pageNo'] = $pageNo;
        if ($pageSize) $params['pageSize'] = $pageSize;
        
        $result_arr = $this->request->get('itemGetAll', $params);
        
        return $result_arr['getItemList'];
        /*
        $result = new UleItemList ();
        
        return $this->__firefillProperty ( $result, $response, UleItemList::$_DataLayerout ['varclass'] );
    	*/
    }
    
    /**
     * @param $itemSku itemId	String	Y	商品ID。	
	 * @param $itemStorage	String	Y	库存数量，取值范围：大于0的整数。	
	 * 
	 * @return true or false
     */
    function itemStorageUpdateBySKU($itemSku, $itemStorage) {
		if (!$itemSku || !is_int($itemStorage)) {
        	throw new UleRuntimeExecption ( - 1, 'UleRuntime.itemStorageUpdateBySKU：参数错误' );
        }
        $params = array('itemSku'=>$itemSku, 'itemStorage'=>$itemStorage);
        $result_arr = $this->request->post('itemStorageUpdateBySKU', $params);
        
        if ($result_arr['returnMessage'] == '操作成功')  {
        	return true;
    	} else {
        	return false;
    	}
    }
    /**
     * 获取当前商家的交易列表，并根据传入的条件对交易信息进行过滤
     * 
     * @param $startTime 	String	N	查询交易创建时间开始。格式:yyyy-MM-dd HH:mm:ss	
     * @param $endTime 		String	N	查询交易创建时间结束。格式:yyyy-MM-dd HH:mm:ss	
     * @param $orderStatus 	String	N	订单状态代码	
     * @param $itemSKU		String	N	商家商品SKU	
     * @param $pageNo		String	N	页码。取值范围:大于零的整数;默认值为1，即返回第一页数据。	
     * @param $pageSize		String	N	每页条数。取值范围:大于零的整数;最大值：200；默认值：50。	
     * 
     * @return	<pre>
     * 			array(
					"tradeTotal":搜索结果总数,
					"trade": array(
						array
						(
							"orderAmount"=>订单总金额
							"orderNumber"=>交易订单号,
							"orderCreateTime"=>订单创建时间,
							"orderPayTime"=>订单支付时间,
							"orderStatus"=>订单状态,
							"orderType"=>交易类型,
							"orderRemark"=>订单备注,
							"receiverName"=>收货人姓名,
							"receiverPhone"=>收货人电话号码,
							"receiverMobile"=>收货人手机号码,
							"receiverProvince"=>收货人省份,
							"receiverCity"=>收货人城市,
							"receiverAddress"=>收货人地址 ,
							"receiverPostcode"=>收货人邮编,
							"receiverRemark"=>收货人备注,
							"merchantAddress"=>商家发货地址,
							"deliveryTime"=>商家发货时间,
							"deliveryFee"=>邮费,
							"packageCode"=>包裹单号，
							"itemInfo"=>  array(
								array
								(
								"itemSKU"=>商家商品SKU,
								"itemName"=>商品名称,
								"itemPrice"=>商品价格,
								"itemQty"=>购买商品数量,
								"itemWeight"=>订单状态,
								"itemAttributes"=>商品属性
								),
								……// 多个item
							)
						},
						……// 多个trade
				)</pre>
     */
    function orderTradesGet($orderStatus=NULL, $pageNo=NULL, $pageSize=NULL, $startTime=NULL, $endTime=NULL,  $itemSKU=NULL) {
    	$params = array();
    	if ($orderStatus) {
    		if (!in_array($orderStatus, UleStatus::$OrderStatus)) {
    			throw new UleRuntimeExecption(-1, '不是有效的订单状态');
    		}
    		$params['orderStatus'] = $orderStatus;
    	}
    	if ($startTime) $params['startTime'] = $startTime;
    	if ($endTime) $params['endTime'] = $endTime;
    	if ($itemSKU) $params['itemSKU'] = $itemSKU;
    	if ($pageNo) $params['pageNo'] = $pageNo;
    	if ($pageSize) $params['pageSize'] = $pageSize;
    	
    	$result_arr = $this->request->get('orderTradesGet', $params);
    	
    	return $result_arr['getTradeOrders'];
    }
    
    /**
     * 根据订单更新包裹单号。
     * 
     * @param $orderNumber 	String	Y	订单号	
     * @param $packageCode 	String	Y	包裹单号	
     * @param $itemWeight 	String	Y	净重	
     * @param $deliveryTime String	Y	发货时间，格式化为：yyyy-MM-dd HH:mm:ss	
     * @param $orderStatus 	String	Y	订单状态；5-已发货；6-配货完成	
     * 
     * @return 	
     * 			<li>true 更新成功
     * 			<li>false 更新失败
     */
    function orderDispatchUpdate($orderNumber, $packageCode, $itemWeight, $deliveryTime, $orderStatus) {
    	$params = array(
					'orderNumber' => $orderNumber,
		            'packageCode' => $packageCode,
		            'itemWeight' => $itemWeight,
		            'deliveryTime' => $deliveryTime,
		            'orderStatus' => $orderStatus
		            );
		$result_arr = $this->request->post('orderTradesGet', $params);
    	
   		if ($result_arr['returnMessage'] == '操作成功')  {
        	return true;
    	} else {
        	return false;
    	}
    }
    
    
    
    private function __setSimpleProperty(ReflectionClass $refclass, $obj, $varname, $varvalue) {
        if ($refclass->hasProperty ( $varname )) {
            $prop = $refclass->getProperty ( $varname );
            $prop->setValue ( $obj, $varvalue );
        }
    }
    private function __fillProperty($refclass, $obj, array &$arr, $complexClass = NULL) {
        foreach ( $arr as $key => $val ) {
            if (! $key) {
                continue;
            } 
            
            if (!$refclass->hasProperty ( $key )) {
                $obj->key = $val;
                continue;
            }
            
            $prop = $refclass->getProperty ( $key );
            
            if (! is_array ( $val )) {     //simple property
                if ($prop->isPrivate () || $prop->isProtected ()) {
                    $prop->setAccessible ( true );
                }
                $prop->setValue ( $obj, $val );
                
            } else {
                $classname = $complexClass [$key];
                if (! $classname)
                    $prop->setValue ( $obj, $val ); //simple set array
                $comprefclass = new ReflectionClass($classname); 
                
                list($first_key, $first_value) = each($val);
                if (!is_int($first_key)) { // obj property
                    $compobj = $comprefclass->newInstance ();
                    
                    $this->__fillProperty ( $comprefclass, $compobj, $val, $complexClass );
                    $this->__setSimpleProperty($comprefclass, $compobj, '__owner', $obj);
                    
                    $prop->setValue ( $obj, $compobj );    // set obj
                    
                } else {    // obj array property
                    reset($val);
                    $obj_list = array();
                    foreach ($val as $k=>$obj_arr) {
                        $compobj = $comprefclass->newInstance ();
                        
                        $this->__fillProperty ( $comprefclass, $compobj, $obj_arr, $complexClass );
                        $this->__setSimpleProperty($comprefclass, $compobj, '__owner', $obj);
                        $obj_list [] = $compobj;
                    }
                    $prop->setValue ( $obj, $obj_list ); //set obj array
                }
            }
            
        }
        return $obj;
    }
    private function __firefillProperty($obj, array &$arr, $complexClass = NULL) {
        if (! $obj || ! $arr || count ( $arr ) == 0)
            return $obj;
        reset ( $arr );
        $realarr = null;
        foreach ( $arr as $k => $v ) {
            if (is_array ( $v )) {
                $realarr = $v;
                break;
            }
        }
        if ($realarr === null)
            return $obj;
        
        if (count ( $realarr ) == 1) {
            list ( $realkey, $realarray ) = each ( $realarr );
            if (! is_array ( $realarray )) { //not normal
                $obj->$realkey = $realarray;
                return $obj;
            }
            list ( $realchildkey, ) = each ( $realarray );
            $firstlen = strlen ( $realchildkey ) - 1;
            if (count ( $realarray ) == 1 && ($realchildkey . 's' == $realkey || substr ( $realchildkey, 0, $firstlen ) == substr ( $realkey, 0, $firstlen )))
                unset ( $realarray );
            else
                $realarr = &$realarray;
            reset ( $realarr );
        }
        if (count ( $realarr ) == 0)
            return $obj;

        version_compare ( PHP_VERSION, '5.3.0' ) < 0;
        $refclass = new ReflectionObject ( $obj );
        $this->__fillProperty ( $refclass, $obj, $realarr, $complexClass );
        $this->__setSimpleProperty ( $refclass, $obj, '__runtime', $this );
        
        return $obj;
    }
    
}